
import 'package:first_flutter_project/main/main.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

import '../Gesture/GestureDetectorConflictTest.dart';
import '../Gesture/GestureDetectorHitTest.dart';
import '../Gesture/NotificationInterruptTest.dart';

///基本的动画用法
class ScaleAnimationRoute extends StatefulWidget {
  @override
  _ScaleAnimationRouteState createState() => _ScaleAnimationRouteState();
}

//需要继承TickerProvider，如果有多个AnimationController，则应该使用TickerProviderStateMixin。
class _ScaleAnimationRouteState extends State<ScaleAnimationRoute>
    with SingleTickerProviderStateMixin {
  late Animation<double> animation;
  late AnimationController controller;
  late Tween<double> tween;

  initState() {
    super.initState();
    controller = AnimationController(
      duration: const Duration(seconds: 2),
      vsync: this,
    );

    //弹性用法速度
    final CurvedAnimation bounceIn =
        CurvedAnimation(parent: controller, curve: Curves.bounceIn);

    //匀速
    //图片宽高从0变到300
    tween = Tween(begin: 0.0, end: 300.0);
    animation = tween.animate(bounceIn)
      ..addListener(() {
        setState(() => {});
      });

    ///addListener()函数调用了setState()，所以每次动画生成一个新的数字时，当前帧被标记为脏(dirty)，
    ///这会导致widget的build()方法再次被调用，
    ///而在build()中，改变Image的宽高，因为它的高度和宽度现在使用的是animation.value ，所以就会逐渐放大。
    ///值得注意的是动画完成时要释放控制器(调用dispose()方法)以防止内存泄漏。

    //启动动画(正向执行)
    controller.forward();
  }

  @override
  Widget build(BuildContext context) {
    return Center(
        child: Column(
      children: [
        TextButton(
          child: Text("开启动画"),
          onPressed: () {
            tween.begin = 0.0;
            tween.end = 300.0;
            if(controller.status == AnimationStatus.completed){
              controller.reverse();
            }else{
              controller.forward();
            }
          },
        ),
        Image.network(
          netWorkImageUrl,
          width: animation.value,
          height: animation.value,
        ),
      ],
    ));
  }

  dispose() {
    //路由销毁时需要释放动画资源
    controller.dispose();
    super.dispose();
  }
}

///ScaleAnimationRoute 上面示例中通过addListener()和setState() 来更新UI这一步其实是通用的，
///如果每个动画中都加这么一句是比较繁琐的。AnimatedWidget类封装了调用setState()的细节，
///并允许我们将 widget 分离出来，重构后的代码如下：
class AnimatedImage extends AnimatedWidget {
  AnimatedImage({
    Key? key,
    required Animation<double> animation,
  }) : super(key: key, listenable: animation);

  Widget build(BuildContext context) {
    final animation = listenable as Animation<double>;
    return Center(
        child: Image.network(
      netWorkImageUrl,
      width: animation.value,
      height: animation.value,
    ));
  }
}

class ScaleAnimationRoute1 extends StatefulWidget {
  @override
  _ScaleAnimationRouteState1 createState() => _ScaleAnimationRouteState1();
}

class _ScaleAnimationRouteState1 extends State<ScaleAnimationRoute1>
    with SingleTickerProviderStateMixin {
  late Animation<double> animation;
  late AnimationController controller;

  initState() {
    super.initState();
    controller =
        AnimationController(duration: const Duration(seconds: 2), vsync: this);
    //图片宽高从0变到300
    animation = Tween(begin: 0.0, end: 300.0).animate(controller);
    //启动动画
    controller.forward();
  }

  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
        child: Column(
      children: [
        AnimatedImage(
          animation: animation,
        ),
        Text(
          "AnimatedBuilder 相当于AnimatedImage 的进阶版",
          style: TextStyle(color: Colors.white, fontSize: 20.0),
        ),
        AnimatedBuilder(
          animation: animation,
          child: Image.network(
            netWorkImageUrl,
            width: animation.value,
            height: animation.value,
          ),
          builder: (BuildContext ctx, child) {
            return Center(
              child: Container(
                height: animation.value,
                width: animation.value,
                child: child,
              ),
            );
          },
        ),
        Text(
          "GrowTransition中使用AnimatedBuilder的封装",
          style: TextStyle(color: Colors.white, fontSize: 20.0),
        ),
        GrowTransition(
          animation: animation,
          child: Image.network(
            netWorkImageUrl,
            width: animation.value,
            height: animation.value,
          ),
        ),
      ],
    ));
  }

  dispose() {
    //路由销毁时需要释放动画资源
    controller.dispose();
    super.dispose();
  }
}

class GrowTransition extends StatelessWidget {
  GrowTransition({
    required this.animation,
    this.child,
  });

  final Widget? child;
  final Animation<double> animation;

  Widget build(BuildContext context) {
    return Center(
      child: AnimatedBuilder(
        animation: animation,
        builder: (BuildContext context, child) {
          return Container(
            height: animation.value,
            width: animation.value,
            child: child,
          );
        },
        child: child,
      ),
    );
  }
}
